//
// Copyright (c) 2024 BPer
//

#ifndef SRC_BPERRTC_BPERRTCDTLS_H_
#define SRC_BPERRTC_BPERRTCDTLS_H_
#include <bperutil/BPerAvcType.h>
#include <bperice/BPerRtcSocket.h>
#include <bperrtp/BPerRtpConstant.h>
#include <bperutil/buffer/BPerBuffer.h>

#if BPer_Enable_Dtls
#include <bperssl/BPerSsl.h>
#include <bperutil/sys/BPerSRtp.h>
#include <bperutil/sys/BPerThread.h>

#if !BPer_Enable_Openssl
#include <mbedtls/entropy.h>
#include <mbedtls/ctr_drbg.h>
#include <mbedtls/error.h>
#include <mbedtls/sha256.h>
#include <mbedtls/md5.h>
typedef struct {
	uint64_t updatedTime;
	uint32_t int_ms, fin_ms;
}BPerMbedTimer;
#endif



typedef enum{
	BPerDtlsRoleClient,
	BPerDtlsRoleServer
}BPerDtlsRole;

typedef enum{
	BPerDtlsStateInit, // Start.
	BPerDtlsStateClientHello, // Should start ARQ thread.
	BPerDtlsStateServerHello, // We are in the first ARQ state.
	BPerDtlsStateClientCertificate, // Should start ARQ thread again.
	BPerDtlsStateServerDone, // We are in the second ARQ state.
	BPerDtlsStateClientDone, // Done.
}BPerDtlsState;

typedef enum{
	BPerDtlsVersionAuto = -1,
	BPerDtlsVersion1_0,
	BPerDtlsVersion1_2
}BPerDtlsVersion;


typedef struct {
	BPerDtlsState state;
	BPerDtlsVersion version;
	BPerBool handshake_done;
	BPerBool isRecvAlert;
	BPerBool isSendAlert;

	BPerBool isStart;
	BPerBool isLoop;
	BPerBool reset_timer_;
	BPerBool isControled;

	int32_t uid;
	bPer_thread_t threadId;

	BPerRtcSocket* sock;
	BPerSRtp* srtp;
	BPerSslCallback* sslCallback;
	BPerCertificate *cer;

#if BPer_Enable_Openssl
	SSL_CTX* sslctx;
	SSL* ssl;

	BIO* bioIn;
	BIO* bioOut;
#else
	BPerMbedTimer mbtimer;
	mbedtls_ssl_context* ssl;
	mbedtls_ssl_config* sslConfig;
	mbedtls_entropy_context* entropy;
	mbedtls_ctr_drbg_context* ctrDrbg;
	mbedtls_tls_prf_types tlsPrf;
	mbedtls_tls_prf_types srtpPrf;
	uint8_t masterSecret[48];
	void* datachannel;
	uint8_t randBytes[2 * 32];
	uint8_t buffer[kRtpPacketSize];
	int32_t bufferLen;
#endif



}BPerDtlsSession;

typedef struct{
	BPerDtlsSession session;
	void (*start)(BPerDtlsSession* session);
	void (*stop)(BPerDtlsSession* session);
	int32_t (*doHandshake)(BPerDtlsSession* session);
	int32_t (*startHandShake)(BPerDtlsSession* session);

	int32_t (*processData)(void* user,BPerDtlsSession* session,char* p,int32_t len);

	int32_t (*sendDtlsAlert)(BPerDtlsSession* session);
	int32_t (*filterData)(BPerDtlsSession* session,uint8_t* data, int32_t size);
	int32_t (*getSrtpKey)(BPerDtlsSession* session,char* recv_key, int *precvkeylen,char* send_key,int *psendkeylen);
	int32_t (*sendSctpData)(BPerDtlsSession* session,uint8_t* pdata, int32_t nb);
}BPerRtcDtls;

int32_t bPer_create_rtcdtls(BPerRtcDtls* dtls,BPerBool isControled);
void bPer_destroy_rtcdtls(BPerRtcDtls* dtls);

#endif
#endif /* SRC_BPERRTC_BPERRTCDTLS_H_ */
